
# ifndef __DFX_TEXTURE_H__
# define __DFX_TEXTURE_H__

# include "dfxCore.h"
# include "dfxImage.h"

namespace DFX
{
    class GraphicsDevice;

    enum TEXTURE_USAGE
    {
        TEXTURE_USAGE_NORMAL = 0x1,
        TEXTURE_USAGE_RENDER_TARGET = 0x2,
        TEXTURE_USAGE_DEPTH_TARGET = 0x4,
        TEXTURE_USAGE_MIPMAP = 0x8,
        TEXTURE_USAGE_DYNAMIC = 0x10
    };

    enum TEXTURE_TYPE
    {
        TEXTURE_TYPE_2D = 0,
        TEXTURE_TYPE_3D,
        TEXTURE_TYPE_CUBE,
        TEXTURE_TYPE_MAX
    };

    enum TEXTURE_FILTER
    {
        TEXTURE_FILTER_NEAREST = 0,
        TEXTURE_FILTER_LINEAR,
        TEXTURE_FILTER_BILINEAR,
        TEXTURE_FILTER_TRILINEAR,
        TEXTURE_FILTER_MAX
    };

    enum TEXTURE_WRAP
    {
        TEXTURE_WRAP_REPEAT,
        TEXTURE_WRAP_CLAMP,
        TEXTURE_WRAP_CLAMPTOEDGE,
        TEXTURE_WRAP_CLAMPTOBORDER,
        TEXTURE_WRAP_MAX
    };

    enum SURFACE_FORMAT
    {
        SURFACE_FORMAT_BGR8,
        SURFACE_FORMAT_BGRA8,
        SURFACE_FORMAT_MAX
    };

    class DFX_EXPORT Texture
    {
    protected:

        GraphicsDevice     *mGraphicsDevice;
        String              mName;
        TEXTURE_TYPE		mType;
        TEXTURE_WRAP		mWrapS;
        TEXTURE_WRAP		mWrapT;
        TEXTURE_WRAP		mWrapR;
        TEXTURE_FILTER		mFilter;

        UInt32				mWidth;
        UInt32				mHeight;
        UInt32				mDepth;
        UInt32				mUsage;
        UInt32				mNumMipMaps;
        bool				mMipMaps;
        UInt32				mBytesPerPixel;
        Float32				mAnisotropy;

    public:

        Texture(const String &name, GraphicsDevice *gd, TEXTURE_TYPE type, UInt32 usage, bool mipMaps = true)
            : mName(name),
            mGraphicsDevice(gd),
            mType(type), 
            mUsage(usage), 
            mMipMaps(mipMaps)
        {
        }

        virtual ~Texture()
        {
        }

        TEXTURE_TYPE GetTextureType() const
        {
            return mType;
        }

        TEXTURE_FILTER GetTextureFilter() const
        {
            return mFilter;
        }
        
        TEXTURE_WRAP GetWrapS() const
        {
            return mWrapS;
        }

        TEXTURE_WRAP GetWrapT() const
        {
            return mWrapT;
        }

        TEXTURE_WRAP GetWrapR() const
        {
            return mWrapR;
        }

        UInt32 GetWidth() const
        {
            return mWidth;
        }

        UInt32 GetHeight() const
        {
            return mHeight;
        }

        UInt32 GetDepth() const
        {
            return mDepth;
        }

        UInt32 GetNumMipMaps() const
        {
            return mNumMipMaps;
        }

        bool HasMipMaps() const
        {
            return mMipMaps;
        }

        Float32 GetAnisotropy() const
        {
            return mAnisotropy;
        }

        UInt32 GetUsage() const
        {
            return mUsage;
        }

        UInt32 GetBytesPerPixel() const
        {
            return mBytesPerPixel;
        }

        virtual DFXRESULT Load2D(Image *img) = 0;
        virtual DFXRESULT LoadCube(const ImageArray &images) = 0;

        virtual DFXRESULT Create(SURFACE_FORMAT format, UInt32 width, UInt32 height, UInt32 depth) = 0;

        virtual void SetFilter(TEXTURE_FILTER filter) = 0;
        virtual void SetAnisotropy(Float32 anisotropy) = 0;

        virtual void SetWrapS(TEXTURE_WRAP wrapS) = 0;
        virtual void SetWrapT(TEXTURE_WRAP wrapT) = 0;
        virtual void SetWrapR(TEXTURE_WRAP wrapR) = 0;
    };
}

# endif